﻿using UnityEngine;
using System.Collections.Generic;
using TTGame;
using System;

/*
 * AnimPlayer
 * 封装Animation，尽量简化动画播放
 *
 *
 * 依赖：
 * Animation
 *
 * ！不写重复代码！
 * @author TTun
 * @date 7/13/2017 4:20:32 PM
 */
namespace TTGameEngine {

[Serializable]
public class AnimPlayer {

    static public bool AnimPlayerLogFlag = true;

    [SerializeField]
    public Animation m_anim;
    [SerializeField]
    string m_curAnimName;
    [SerializeField]
    bool m_isPause = false;
    [SerializeField]
    float animSpeedBeforePause = 1f;

    public AnimPlayer(Animation anim) {
        m_anim = anim;
    }

    bool CheckAnimName(string name, bool isLog = true) {
        if(string.IsNullOrEmpty(name) || m_anim == null || m_anim[name] == null) {
            if(isLog) {
                AnimLogError(name,
                             "AnimName[{0}] check Error. anim is {1}, m_anim[{0}] is {2}",
                             name,
                             m_anim == null ? "Null" : "Not Null",
                             m_anim[name] == null ? "Null" : "Not Null"
                            );
            }
            return false;
        }
        return true;
    }

    public void PlayAnimWithFade(string name, float fadeLength = 0f, PlayMode playMode = PlayMode.StopAll) {
        if(CheckAnimName(name) == false) {
            return;
        }
        if(m_isPause) {
            return;
        }
        if(fadeLength > m_anim[name].length) {
            fadeLength = m_anim[name].length;
        }
        AnimLog(name, "CrossFade Anim. lastAnim:->[{0}]", m_curAnimName, AnimDump(m_curAnimName));

        m_curAnimName = name;
        //fixAnim(name);
        m_anim.Rewind(name);
        m_anim.CrossFade(name, fadeLength, playMode);
    }

    public void PlayAnimWithBlenad(string name, float towardWeight = 1.0f, float fadeLength = 0f) {
        if(CheckAnimName(name) == false) {
            return;
        }
        if(m_isPause) {
            return;
        }
        if(fadeLength > m_anim[name].length) {
            fadeLength = m_anim[name].length;
        }
        AnimLog(name, "CrossFade Anim. lastAnim:->[{0}]", m_curAnimName, AnimDump(m_curAnimName));

        m_curAnimName = name;
        m_anim.Rewind(name);
        m_anim.Blend(name, towardWeight, fadeLength);
    }

    //防止动画播放完毕后，后面crossfade的动画没有效果。
    void fixAnim(string animname) {
        WrapMode wrapmode = m_anim[animname].wrapMode;
        if(wrapmode == WrapMode.Clamp || wrapmode == WrapMode.Once || wrapmode == WrapMode.Default) {
            wrapmode = WrapMode.ClampForever;
        }
        m_anim[animname].wrapMode = wrapmode;
    }


    public bool SetupAnim(string name, int layer, float speed, WrapMode mode) {
        if(CheckAnimName(name, false) == false) {
            return false;
        }
        m_curAnimName = name;
        m_anim[name].layer = layer;
        if(speed >= 0)  m_anim[name].speed = speed;
        m_anim[name].wrapMode = mode;
        return true;
    }
    public AnimationState GetAnimation(string name) {
        if(CheckAnimName(name) == false) {
            return null;
        }
        return m_anim[name];
    }

    public float GetAnimLength(string name) {
        if(CheckAnimName(name) == false) {
            return 0;
        }
        return m_anim[name].length;
    }

    public void SetSpeed(string name, float speed) {
        if(CheckAnimName(name) == false) {
            return;
        }
        m_anim[name].speed = speed;
    }

    public void SetWrapMode(string name, WrapMode mode) {
        if(CheckAnimName(name) == false) {
            return;
        }
        m_anim[name].wrapMode = mode;
    }

    public void Pause() {
        if(m_isPause) {
            return;
        }
        m_isPause = true;
        animSpeedBeforePause = m_anim[m_curAnimName].speed;
        m_anim[m_curAnimName].speed = 0f;
    }

    public void Resume() {
        if(!m_isPause) {
            return;
        }
        m_isPause = false;
        m_anim[m_curAnimName].speed = animSpeedBeforePause;
        animSpeedBeforePause = 1.0f;
    }

    /// <summary>
    /// 注意：loop\clampForever时动画会一直播放。
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public bool IsAnimPlaying(string name) {
        if(CheckAnimName(name) == false) {
            return false;
        }
        //不能使用enabled，因为都被我强制设置成clampForever了。
        if(m_anim[name].wrapMode == WrapMode.Loop) {
            return true;
        }
        return m_anim[name].time < m_anim[name].length;
    }

    void AnimLog(string newAnimName, string msgformat, params object[] args) {
        if(AnimPlayerLogFlag == false) {
            return;
        }
        DebugUtil.LogFormat("[AnimPlayer][{0}] {1}  \n NewAnim->[{2}]",
                            m_anim.gameObject.name,
                            string.Format(msgformat, args),
                            AnimDump(newAnimName)
                           );
    }

    void AnimLogError(string newAnimName, string msgformat, params object[] args) {
        DebugUtil.LogErrorFormat("[AnimPlayer][{0}] {1}  \n NewAnim->[{2}]",
                                 m_anim.gameObject.name,
                                 string.Format(msgformat, args),
                                 AnimDump(newAnimName)
                                );
    }

    public string AnimDump(string name) {
        if(string.IsNullOrEmpty(name)) {
            return "";
        }
        return string.Format("anim:[{0}] len:[{1}] speed[{2}] enabled[{3}]",
                             name,
                             m_anim[name] != null ? m_anim[name].length.ToString() : "0",
                             m_anim[name] != null ? m_anim[name].speed.ToString() : "0",
                             m_anim[name] != null ? m_anim[name].enabled.ToString() : "0"
                            );
    }
}

}
